package com.chenfan.mcn.controller;

import com.alibaba.fastjson.JSONObject;
import com.chenfan.mcn.enums.LogBusinessTypeEnum;
import com.chenfan.mcn.extension.log.FieldChangeOperateLog;
import com.chenfan.mcn.clients.finance.FinanceClient;
import com.chenfan.mcn.config.UserVoContextHolder;
import com.chenfan.mcn.constant.BillCodeCst;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.constant.McnConstant;
import com.chenfan.mcn.enums.ImportExcelEnum;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.mcn.extension.excel.ExcelUtils;
import com.chenfan.mcn.component.OperateLogHandler;
import com.chenfan.mcn.model.*;
import com.chenfan.mcn.model.common.PageInfo;
import com.chenfan.mcn.model.vo.BillIdVO;
import com.chenfan.mcn.service.*;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 公共接口管理
 *
 * @author wulg
 * @date 2021-06-24
 **/
@Slf4j
@RestController
public class CommonController {

    @Autowired
    private ContractExcutionOrderService excutionOrderService;

    @Autowired
    private IncomeContractService incomeContractService;

    @Autowired
    private DiscountApprovalService discountApprovalService;

    @Autowired
    private AnnualRebateApprovalService annualRebateApprovalService;

    @Autowired
    private StarRebateContractService starRebateContractService;

    @Autowired
    private StarMonthlySettlementService starMonthlySettlementService;

    @Autowired
    private LiveStarSettlementService liveStarSettlementService;

    @Autowired
    private FinanceClient financeClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 通过单据编号获取单据ID
     * @param billCode
     * @param type
     * @return
     */
    @GetMapping("/bill/getIdByCode")
    public Res<BillIdVO> getIdByCode(@RequestParam("billCode") String billCode, String type) {
        Assert.isTrue(StringUtils.isNotBlank(billCode), "单据编号不能为空");
        BillIdVO billIdVO = new BillIdVO();
        if (billCode.startsWith(BillCodeCst.CF_INVOICE)) {
            //财务账单
            billIdVO.setType(BillCodeCst.CF_INVOICE);
            billIdVO.setId(financeClient.getInvoiceIdByNo(billCode).getObj());
        } else if (StringUtils.startsWithAny(billCode, BillCodeCst.EXCUTION_ORDER, McnConstant.NZXD, McnConstant.WZXD)) {
            //执行单
            billIdVO.setType(BillCodeCst.EXCUTION_ORDER);
            ContractExcutionOrder entity = excutionOrderService.getByCode(billCode);
            billIdVO.setId(Optional.ofNullable(entity).map(contractExcutionOrder -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.INCOME_CONTRACT)) {
            //收入合同
            billIdVO.setType(BillCodeCst.INCOME_CONTRACT);
            IncomeContract entity = incomeContractService.getByCode(billCode, UserVoContextHolder.getTenantId());
            billIdVO.setId(Optional.ofNullable(entity).map(incomeContract -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.DISCOUNT_APPROVAL) || (Objects.equals(type, BillCodeCst.DISCOUNT_APPROVAL))) {
            //折扣返点审批单
            billIdVO.setType(BillCodeCst.DISCOUNT_APPROVAL);
            DiscountApproval entity = discountApprovalService.getByCode(billCode);
            billIdVO.setId(Optional.ofNullable(entity).map(discountApproval -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.ANNUAL_REBATE_APPROVAL)) {
            //年度返点审批单
            billIdVO.setType(BillCodeCst.ANNUAL_REBATE_APPROVAL);
            AnnualRebateApproval entity = annualRebateApprovalService.getByCode(billCode);
            billIdVO.setId(Optional.ofNullable(entity).map(annualRebateApproval -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.STAR_REBATE_APPROVAL)) {
            //红人返点合同
            billIdVO.setType(BillCodeCst.STAR_REBATE_APPROVAL);
            StarRebateContract entity = starRebateContractService.getByCode(billCode, UserVoContextHolder.getTenantId());
            billIdVO.setId(Optional.ofNullable(entity).map(starRebateContract -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.STAR_MONTHLY_SETTLEMENT)) {
            //红人月度结算单
            billIdVO.setType(BillCodeCst.STAR_MONTHLY_SETTLEMENT);
            StarMonthlySettlement entity = starMonthlySettlementService.getSettlementByCode(billCode, false);
            billIdVO.setId(Optional.ofNullable(entity).map(starMonthlySettlement -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.STAR_MONTHLY_SETTLEMENT_SUB)) {
            //红人月度-子结算单
            billIdVO.setType(BillCodeCst.STAR_MONTHLY_SETTLEMENT_SUB);
            StarMonthlySettlementSub entity = starMonthlySettlementService.getSubSettlementByCode(billCode, false);
            billIdVO.setId(Optional.ofNullable(entity).map(starMonthlySettlementSub -> entity.getId()).orElse(null));
        } else if (billCode.startsWith(BillCodeCst.LIVE_STAR_SETTLEMENT)) {
            //直播红人结算单
            billIdVO.setType(BillCodeCst.LIVE_STAR_SETTLEMENT);
            LiveStarSettlement entity = liveStarSettlementService.getSettlementByCode(billCode, false);
            billIdVO.setId(Optional.ofNullable(entity).map(liveStarSettlement -> entity.getId()).orElse(null));
        }else {
            throw new BusinessException(McnErrorCode.ILLEGAL_BILL_CODE);
        }
        return Res.ok(billIdVO);
    }

    /**
     * 分页查询操作日志
     * @param pageNum 当前页
     * @param pageSize 每页大小
     * @param bussinessType 业务类型
     * @param businessId 业务ID
     * @return
     */
    @GetMapping(value = "/log/page", produces = {"application/json;charset=UTF-8"})
    public Res<PageInfo<FieldChangeOperateLog>> page(@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
                                                     @RequestParam(name = "pageSize", defaultValue = "30") Integer pageSize,
                                                     @RequestParam(name = "businessId", required = false) Long businessId,
                                                     @RequestParam(name = "bussinessType", required = false) Integer bussinessType) {
        BusinessAssert.notNull(businessId, McnErrorCode.PARAM_ERROR, "日志业务ID不能为空");
        BusinessAssert.notNull(bussinessType, McnErrorCode.PARAM_ERROR, "日志业务类型不能为空");
        List<Integer> bussinessTypes = null;
        if (LogBusinessTypeEnum.INCOME_CONTRACT.getType().equals(bussinessType)) {
            bussinessTypes = Arrays.asList(LogBusinessTypeEnum.INCOME_CONTRACT.getType(),
                    LogBusinessTypeEnum.INCOME_CONTRACT_AGREEMENT.getType(),
                    LogBusinessTypeEnum.INCOME_CONTRACT_COMMENT.getType());
        } else if (LogBusinessTypeEnum.YEAR_FRAME_CONTRACT.getType().equals(bussinessType)) {
            bussinessTypes = Arrays.asList(LogBusinessTypeEnum.YEAR_FRAME_CONTRACT.getType(),
                    LogBusinessTypeEnum.YEAR_SUPPLEMENTARY_AGREEMENT.getType(),
                    LogBusinessTypeEnum.YEAR_FRAME_CONTRACT_COMMENT.getType());
        } else if (LogBusinessTypeEnum.EXECUTION_ORDER.getType().equals(bussinessType)) {
            bussinessTypes = Arrays.asList(LogBusinessTypeEnum.EXECUTION_ORDER.getType(),
                    LogBusinessTypeEnum.EXECUTION_ORDER_COMMENT.getType());
        } else if (LogBusinessTypeEnum.STAR_INFO.getType().equals(bussinessType)) {
            bussinessTypes = Arrays.asList(LogBusinessTypeEnum.STAR_INFO.getType(),
                    LogBusinessTypeEnum.STAR_CONTACT_PERSON.getType(),
                    LogBusinessTypeEnum.STAR_PLATFORM_INFO.getType(),
                    LogBusinessTypeEnum.STAR_CONTRACT.getType(),
                    LogBusinessTypeEnum.STAR_ACCOUNT_INFO.getType());
        } else {
            bussinessTypes = Arrays.asList(bussinessType);
        }
        return Res.ok(OperateLogHandler.selectLogs(pageNum, pageSize, businessId, bussinessTypes));
    }

    /**
     * 下载失败原因
     * @param response
     * @param fileId 文件ID
     */
    @Deprecated
    @GetMapping("/downloadExcel/failedReason")
    public void downloadFailedReason(HttpServletResponse response, @RequestParam("fileId") String fileId) {
        log.error("收到下载失败原因请求，fileId={}", fileId);
        ImportExcelEnum importExcelEnum = ImportExcelEnum.toEnum(fileId);
        BusinessAssert.notNull(importExcelEnum, McnErrorCode.EXPORT_FILE_ID_ILLEGAL);
        try {
            String excelContent = CommonUtil.defaultIfEmpty(stringRedisTemplate.opsForValue().get(McnConstant.CACHE_PRIFIX + fileId));
            List<Object> outputList = CommonUtil.defaultList(JSONObject.parseArray(excelContent, importExcelEnum.getOutputClass()));
            String title = importExcelEnum.getTitle();
            ExcelUtils.exportExcel(outputList, title, importExcelEnum.getOutputClass(), title + ".xlsx", response);
            stringRedisTemplate.delete(McnConstant.CACHE_PRIFIX + fileId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
